﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace EM.OA.Common.Helper
{
    public class EmailHelper
    {
        MailAddress MailAddress_from = null; //设置发信人地址  当然还需要密码
        MailAddress MailAddress_to = null;  //设置收信人地址  不需要密码
        MailMessage MailMessage_Mai = null;
        FileStream FileStream_my = null; //附件文件流

        #region 发送邮件

        /// <summary>
        /// C#发送邮件函数
        /// </summary>
        /// <param name="sfrom">发送者邮箱</param>
        /// <param name="sfromer">发送人</param>
        /// <param name="sto">接受者邮箱</param>
        /// <param name="stoer">收件人</param>
        /// <param name="sSubject">主题</param>
        /// <param name="sBody">内容</param>
        /// <param name="sfile">附件</param>
        /// <param name="sSMTPHost">smtp服务器</param>
        /// <param name="sSMTPuser">邮箱</param>
        /// <param name="sSMTPpass">密码</param>
        /// <returns></returns>
        public bool sendmail(string sfrom, string sfromer, string sto, string stoer, string sSubject, string sBody, string sfile, string sSMTPHost, string sSMTPuser, string sSMTPpass)
        {
            ////设置from和to地址
            MailAddress from = new MailAddress(sfrom, sfromer);
            MailAddress to = new MailAddress(sto, stoer);

            ////创建一个MailMessage对象
            MailMessage oMail = new MailMessage(from, to);

            //清空历史附件  以防附件重复发送
            oMail.Attachments.Clear();
            //// 添加附件
            if (sfile != "")
            {
                oMail.Attachments.Add(new Attachment(sfile));
            }

            ////邮件标题
            oMail.Subject = sSubject;


            ////邮件内容
            oMail.Body = sBody;

            ////邮件格式
            oMail.IsBodyHtml = false;

            ////邮件采用的编码
            oMail.BodyEncoding = System.Text.Encoding.GetEncoding("GB2312");

            ////设置邮件的优先级为高
            oMail.Priority = MailPriority.High;

            ////发送邮件
            SmtpClient client = new SmtpClient();
            ////client.UseDefaultCredentials = false; 
            client.Host = sSMTPHost;
            client.Credentials = new NetworkCredential(sSMTPuser, sSMTPpass);
            client.DeliveryMethod = SmtpDeliveryMethod.Network;
            try
            {
                client.Send(oMail);
                return true;
            }
            catch (Exception err)
            {
                return false;
            }
            finally
            {
                ////释放资源
                oMail.Dispose();
            }

        }

        #endregion

        #region 检测附件大小
        private bool Attachment_MaiInit(string path)
        {

            try
            {
                FileStream_my = new FileStream(path, FileMode.Open);
                string name = FileStream_my.Name;
                int size = (int)(FileStream_my.Length / 1024/1024);
                FileStream_my.Close();
                //控制文件大小不大于10Ｍ
                if (size > 10)
                {
                    return false;
                }
                return true;
            }
            catch (IOException e)
            {
                return false;
            }
        }
        #endregion


    }

    /// <summary>
    /// 电子邮件操作类。
    /// </summary>
    public class Mail
    {
        #region 属性
        private string _subject;
        private string _body;
        private string _from;
        private string _fromName;
        private string _recipientName;
        private string _serverHost;
        private int _serverPort;
        private string _username;
        private string _password;
        private bool _isBodyHtml;
        private string _recipient;
        private List<string> _attachment = new List<string> { };

        #region 获取属性

        /// <summary> 获取或设置邮件的主题。 </summary>
        public string Subject
        {
            get { return this._subject; }
            set { this._subject = value; }
        }

        /// <summary> 获取或设置邮件的正文内容。 </summary>
        public string Body
        {
            get { return this._body; }
            set { this._body = value; }
        }

        /// <summary> 获取或设置发件人的邮件地址。 </summary>
        public string From
        {
            get { return this._from; }
            set { this._from = value; }
        }

        /// <summary> 获取或设置发件人的姓名。 </summary>
        public string FromName
        {
            get { return this._fromName; }
            set { this._fromName = value; }
        }

        /// <summary> 获取或设置收件人的姓名。 </summary>
        public string RecipientName
        {
            get { return this._recipientName; }
            set { this._recipientName = value; }
        }

        /// <summary> 获取或设置收件人的邮件地址。 </summary>
        public string Recipient
        {
            get { return this._recipient; }
            set { this._recipient = value; }
        }

        /// <summary> 获取或设置邮件服务器主机地址。</summary>
        public string ServerHost
        {
            get { return this._serverHost; }
            set { this._serverHost = value; }
        }

        /// <summary> 获取或设置邮件服务器的端口号。 </summary>
        public int ServerPort
        {
            set { this._serverPort = value; }
            get { return this._serverPort; }
        }


        /// <summary> 获取或设置SMTP认证时使用的用户名。 </summary>
        public string Username
        {
            get { return this._username; }
            set
            {
                if (value.Trim() != "")
                {
                    this._username = value.Trim();
                }
                else
                {
                    this._username = "";
                }
            }
        }

        /// <summary> 获取或设置SMTP认证时使用的密码。 </summary>
        public string Password
        {
            set { this._password = value; }
            get { return this._password; }
        }

        /// <summary> 获取或设置指示邮件正文是否为 Html 格式的值。 </summary>
        public bool IsBodyHtml
        {
            get { return this._isBodyHtml; }
            set { this._isBodyHtml = value; }
        }

        /// <summary> 获取电子邮件附件。 </summary>
        public List<string> Attachment
        {
            get { return this._attachment; }
            set { this._attachment = value; }
        }
        #endregion
        #endregion

        #region 初始化
        /// <summary>
        /// 初始化一个电子邮件操作类的空实例。
        /// </summary>
        public Mail()
        {
        }

        /// <summary> 初始化一个电子邮件操作类的实例。 </summary>
        /// <param name="from">发件人的电子邮件地址。</param>
        /// <param name="fromName">发件人的姓名。</param>
        /// <param name="recipient">收件人的电子邮件地址。</param>
        /// <param name="recipientName">收件人的姓名。</param>
        /// <param name="subject">电子邮件的主题。</param>
        /// <param name="body">电子邮件的内容。</param>
        /// <param name="host">电子邮件的服务器地址。</param>
        /// <param name="port">电子邮件的主机端口号。</param>
        /// <param name="username">登录电子邮件服务器的用户名。</param>
        /// <param name="password">登录电子邮件服务器的用户密码。</param>
        /// <param name="isBodyHtml">邮件的正文是否是HTML格式。</param>
        /// <param name="file">邮件附件的文件路径。</param>
        public Mail(string from, string fromName, string recipient, string recipientName, string subject, string body, string host, int port, string username, string password, bool isBodyHtml, string filepath)
        {
            this._from = from;
            this._fromName = fromName;
            this._recipient = recipient;
            this._recipientName = recipientName;
            this._subject = subject;
            this._body = body;
            this._serverHost = host;
            this._serverPort = port;
            this._username = username;
            this._password = password;
            this._isBodyHtml = isBodyHtml;
            this._attachment.Add(filepath);
        }

        /// <summary> 初始化一个电子邮件操作类的实例。 </summary>
        /// <param name="from">发件人的电子邮件地址。</param>
        /// <param name="fromName">发件人的姓名。</param>
        /// <param name="recipient">收件人的电子邮件地址。</param>
        /// <param name="recipientName">收件人的姓名。</param>
        /// <param name="subject">电子邮件的主题。</param>
        /// <param name="body">电子邮件的内容。</param>
        /// <param name="host">电子邮件的服务器地址。</param>
        /// <param name="port">电子邮件的主机端口号。</param>
        /// <param name="username">登录电子邮件服务器的用户名。</param>
        /// <param name="password">登录电子邮件服务器的用户密码。</param>
        /// <param name="isBodyHtml">邮件的正文是否是HTML格式。</param>
        public Mail(string from, string fromName, string recipient, string recipientName, string subject, string body, string host, int port, string username, string password, bool isBodyHtml)
            : this(from, fromName, recipient, recipientName, subject, body, host, 25, username, password, isBodyHtml, null)
        {
        }

        /// <summary> 初始化一个电子邮件操作类的实例。 </summary>
        /// <param name="from">发件人的电子邮件地址。</param>
        /// <param name="fromName">发件人的姓名。</param>
        /// <param name="recipient">收件人的电子邮件地址。</param>
        /// <param name="recipientName">收件人的姓名。</param>
        /// <param name="subject">电子邮件的主题。</param>
        /// <param name="body">电子邮件的内容。</param>
        /// <param name="host">电子邮件的服务器地址。</param>
        /// <param name="port">电子邮件的主机端口号。</param>
        /// <param name="username">登录电子邮件服务器的用户名。</param>
        /// <param name="password">登录电子邮件服务器的用户密码。</param>
        /// <param name="isBodyHtml">邮件的正文是否是HTML格式。</param>
        public Mail(string from, string fromName, string recipient, string recipientName, string subject, string body, string host, string username, string password)
            : this(from, fromName, recipient, recipientName, subject, body, host, 25, username, password, false, null)
        {
        }
        /// <summary> 初始化一个电子邮件操作类的实例（邮件的正文非HTML格式，端口默认25）。 </summary>
        /// <param name="from">发件人的电子邮件地址。</param>
        /// <param name="recipient">收件人的电子邮件地址。</param>
        /// <param name="subject">电子邮件的主题。</param>
        /// <param name="body">电子邮件的内容。</param>
        /// <param name="host">电子邮件的服务器地址。</param>
        /// <param name="username">登录电子邮件服务器的用户名。</param>
        /// <param name="password">登录电子邮件服务器的用户密码。</param>
        /// <param name="isBodyHtml">邮件的正文是否是HTML格式。</param>
        public Mail(string from, string recipient, string subject, string body, string host, string username, string password)
            : this(from, null, recipient, null, subject, body, host, 25, username, password, false, null)
        {
        }
        /// <summary> 初始化一个电子邮件操作类的实例（邮件的正文非HTML格式，端口默认25）。 </summary>
        /// <param name="from">发件人的电子邮件地址。</param>
        /// <param name="recipient">收件人的电子邮件地址。</param>
        /// <param name="subject">电子邮件的主题。</param>
        /// <param name="body">电子邮件的内容。</param>
        /// <param name="port">电子邮件的主机端口号。</param>
        /// <param name="host">电子邮件的服务器地址。</param>
        /// <param name="username">登录电子邮件服务器的用户名。</param>
        /// <param name="password">登录电子邮件服务器的用户密码。</param>
        public Mail(string from, string recipient, string subject, string body, string host, int port, string username, string password)
            : this(from, null, recipient, null, subject, body, host, port, username, password, false, null)
        {
        }

        #endregion

        ///// <summary>
        ///// 添加一个收件人的邮箱地址。
        ///// </summary>
        ///// <param name="mailList">联系人列表。</param>
        ///// <returns></returns>
        //public bool AddRecipient(params string[] mailList)
        //{
        //    this.Recipient = mailList[0].Trim();
        //    return true;
        //}

        /// <summary> 添加电子邮件附件。 </summary>
        /// <param name="fileList">文件列表。</param>
        /// <returns>是否添加成功。</returns>
        public bool AddAttachment(params string[] fileList)
        {
            if (fileList.Length > 0)
            {
                foreach (string file in fileList)
                {
                    if (file != null)
                    {
                        this._attachment.Add(file);
                    }
                    else
                    {
                        return false;
                    }
                }
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary> 发送电子邮件。 </summary>
        /// <returns>是否发送成功。</returns>
        public bool Send()
        {
            //初始化 MailMessage 对象。
            MailMessage mail = new MailMessage();
            Encoding encoding = Encoding.GetEncoding("utf-8");
            mail.From = new MailAddress(this.From, this.FromName, encoding);
            mail.To.Add(new MailAddress(this.Recipient, this.RecipientName));
            mail.Subject = this.Subject;
            mail.IsBodyHtml = this.IsBodyHtml;
            mail.Body = this.Body;
            mail.Priority = MailPriority.Normal;
            mail.BodyEncoding = encoding;
            if (this.Attachment.Count > 0)
            {
                foreach (string file in this.Attachment)
                {
                    mail.Attachments.Add(new Attachment(file));
                }
            }
            //初始化 SmtpClient 对象。
            SmtpClient smtp = new SmtpClient();
            smtp.Host = this.ServerHost;
            smtp.Port = this.ServerPort;
            smtp.Credentials = new NetworkCredential(this.Username, this.Password);
            if (smtp.Port != 25)
            {
                smtp.EnableSsl = true;
            }
            try
            {
                smtp.Send(mail);
            }
            catch (SmtpException ex)
            {
                string message = ex.Message;
                return false;
            }
            return true;
        }
    }

}
